Dans ce dossier nous allons étudier 6 fonds indiciels que sont : le S&P500, l’indice boursier européen, les fonds de marchés émergents, les fonds d’obligations à long et à court terme, et l’indice boursier du Pacifique. Nous commencerons l’analyse par les calculs de rendements, de statistiques et de performance des titres, puis nous verrons la théorie moderne de portefeuille dans une deuxième partie. Les valeurs des indices sont récoltées quotidiennement du 1er décembre 2018 au 30 novembre 2019 sur le site de Yahoo Finance.
library(dplyr)
library(questionr)
library(data.table)
library(scales)
library(ggplot2)
library(tseries)
library(RColorBrewer)
library(moments)
library(PerformanceAnalytics)
library(corrplot)
library(zoo)
library(ggplot2)
library(scales)
library(ggrepel)
library(extrafont);loadfonts()
VFINX <- read.csv("VFINX.csv")
VEURX <- read.csv("VEURX.csv")
VEIEX <- read.csv("VEIEX.csv")
VBLTX <- read.csv("VBLTX.csv")
VBISX <- read.csv("VBISX.csv")
VPACX <- read.csv("VPACX.csv")
base <- left_join(VFINX,VEURX, by="Date")
base <- left_join(base,VEIEX, by="Date")
base <- left_join(base,VBLTX, by="Date")
base <- left_join(base,VBISX, by="Date")
base <- left_join(base,VPACX, by="Date")
base <- base [, c("Date", "Adj.Close.x", "Adj.Close.y", "Adj.Close.x.x", "Adj.Close.y.y", "Adj.Close.x.x.x", "Adj.Close.y.y.y")]
names(base)
## [1] "Date" "Adj.Close.x" "Adj.Close.y" "Adj.Close.x.x"
## [5] "Adj.Close.y.y" "Adj.Close.x.x.x" "Adj.Close.y.y.y"
base <-rename.variable(base,"Adj.Close.x","VFINX")
base <-rename.variable(base,"Adj.Close.y","VEURX")
base <-rename.variable(base,"Adj.Close.x.x","VEIEX")
base <-rename.variable(base,"Adj.Close.y.y","VBLTX")
base <-rename.variable(base,"Adj.Close.x.x.x","VBISX")
base <-rename.variable(base,"Adj.Close.y.y.y","VPACX")
names(base)
## [1] "Date" "VFINX" "VEURX" "VEIEX" "VBLTX" "VBISX" "VPACX"
str(base)
## 'data.frame': 251 obs. of 7 variables:
## $ Date : chr "2018-11-30" "2018-12-03" "2018-12-04" "2018-12-06" ...
## $ VFINX: num 251 254 245 245 239 ...
## $ VEURX: num 26.7 27 26.5 26 25.8 ...
## $ VEIEX: num 24.4 24.8 24.5 24.2 23.9 ...
## $ VBLTX: num 12.4 12.5 12.6 12.6 12.6 ...
## $ VBISX: num 10 10 10 10 10 ...
## $ VPACX: num 12.2 12.3 12 11.9 11.8 ...
base$Date <- as.Date(base$Date)
dim(base)
## [1] 251 7
Notre base est donc créée, elle est composée de 251 lignes qui correspondent aux valeurs des indices sur la période du 1er décembre 2018 au 30 novembre 2019, et de 7 colonnes : la date, suivie des 6 indices. Tous les indices sont composés de 251 périodes sauf l’indice “VBLTX” qui en a 238. Ainsi, pour certaines manipulations nous utiliserons une base débarassée des valeurs manquantes, appelée “base1” de dimensions [238:7].
base <- data.table(base)
base[, Prix1 :=VFINX/VFINX[1]]
base[, Prix2 :=VEURX/VEURX[1]]
base[, Prix3 :=VEIEX/VEIEX[1]]
base[, Prix4 :=VBLTX/VBLTX[1]]
base[, Prix5 :=VBISX/VBISX[1]]
base[, Prix6 :=VPACX/VPACX[1]]
round(sapply(base[,8:13],mean, na.rm=TRUE),4)
## Prix1 Prix2 Prix3 Prix4 Prix5 Prix6
## 1.0479 1.0579 1.0557 1.1373 1.0344 1.0178
On constate que les prix relatifs évoluent beaucoup, nous supposons donc qu’ils sont très sensibles aux événements extérieurs. Si l’on regarde les prix moyens de chaque fond, on voit qu’ils sont tous supérieurs à 1 - donc en moyenne les prix ont augmenté sur la période. C’est l’indice n°4, c’est à dire, ‘VBLTX’ qui a le prix moyen le plus élevé : en moyenne du 1er décembre 2018 au 12 novembre 2019 les prix de ce fond ont augmenté de 13.73% par rapport au 1er décembre 2018. À contrario l’indice ayant le prix moyen le plus faible est le VPACX pour lequel les prix ont augmetné de seulement 1.78% par rapport au 1er décembre 2018.
base[, Rdmts1 := VFINX / shift(VFINX, 1) - 1]
base[, Rdmts2 := VEURX / shift(VEURX, 1) - 1]
base[, Rdmts3 := VEIEX / shift(VEIEX, 1) - 1]
base[, Rdmts4 := VBLTX / shift(VBLTX, 1) - 1]
base[, Rdmts5 := VBISX / shift(VBISX, 1) - 1]
base[, Rdmts6 := VPACX / shift(VPACX, 1) - 1]
round(sapply(base[,14:19],mean, na.rm=TRUE)*100,4)
## Rdmts1 Rdmts2 Rdmts3 Rdmts4 Rdmts5 Rdmts6
## 0.0636 0.0535 0.0377 0.0840 0.0226 0.0336
Les rendements connaissent eux aussi beaucoup de fluctuations, ils semblent très volatiles. Ils ne sont pas très élevés (variant de 0.023% à 0.084%) mais sont tous positifs. Tout comme pour les prix, le rendement moyen le plus élevé est celui du fond ‘VBLTX’, en revanche le plus faible est ici celui du fond ‘VBISX’ qui s’élève à 0.023%.
ggplot(base, aes(x = Date, y = Prix1, color = VFINX)) +
geom_line(cex=1.5) +
geom_hline(aes(yintercept=1.0479), col="red", cex=1) +
geom_smooth(se=FALSE, col="black") +
theme_bw() + ggtitle("Évolution du prix de l'indice VFINX") +
xlab("Date") + ylab("Prix : base=1 le 30/11/2018") +
scale_color_continuous(name = "Indice") +
labs(caption="Prix moyen=1.0479")
ggplot(base, aes(x = Date, y = Prix2, color = VEURX)) +
geom_line(cex=1.5) +
geom_hline(aes(yintercept=1.0579), col="red", cex=1) +
geom_smooth(se=FALSE, col="black") +
theme_bw() + ggtitle("Évolution du prix de l'indice VEURX") +
xlab("Date") + ylab("Prix : base=1 le 30/11/2018") +
scale_color_continuous(name = "Indice") +
labs(caption="Prix moyen=1.0579")
ggplot(base, aes(x = Date, y = Prix3, color = VEIEX)) +
geom_line(cex=1.5) +
geom_hline(aes(yintercept=1.0557), col="red", cex=1) +
geom_smooth(se=FALSE, col="black") +
theme_bw() + ggtitle("Évolution du prix de l'indice VEIEX") +
xlab("Date") + ylab("Prix : base=1 le 30/11/2018") +
scale_color_continuous(name = "Indice") +
labs(caption="Prix moyen=1.0557")
ggplot(base, aes(x = Date, y = Prix4, color = VBLTX)) +
geom_line(cex=1.5) +
geom_hline(aes(yintercept=1.1373), col="red", cex=1) +
geom_smooth(se=FALSE, col="black") +
theme_bw() + ggtitle("Évolution du prix de l'indice VBLTX") +
xlab("Date") + ylab("Prix : base=1 le 30/11/2018") +
scale_color_continuous(name = "Indice") +
labs(caption="Prix moyen=1.1373")
ggplot(base, aes(x = Date, y = Prix5, color = VBISX)) +
geom_line(cex=1.5) +
geom_hline(aes(yintercept=1.0344), col="red", cex=1) +
geom_smooth(se=FALSE, col="black") +
theme_bw() + ggtitle("Évolution du prix de l'indice VBISX") +
xlab("Date") + ylab("Prix : base=1 le 30/11/2018") +
scale_color_continuous(name = "Indice") +
labs(caption="Prix moyen=1.0344")
ggplot(base, aes(x = Date, y = Prix6, color = VPACX)) +
geom_line(cex=1.5) +
geom_hline(aes(yintercept=1.0178), col="red", cex=1) +
geom_smooth(se=FALSE, col="black") +
theme_bw() + ggtitle("Évolution du prix de l'indice VPACX") +
xlab("Date") + ylab("Prix : base=1 le 30/11/2018") +
scale_color_continuous(name = "Indice") +
labs(caption="Prix moyen=1.0178")
Nous avons en rouge le prix moyen dont la valeur exacte est donnée en bas à droite du graphique, ainsi que l’allure de l’évolution en noir sur les graphiques. Les courbes d’évolution des prix sont différentes d’un fond à l’autre mais nous pouvons tout de même distinguer 2 groupes :
ggplot(base,aes(x=Date), col())+
geom_line(aes(y=Prix1),colour="red",lwd=1)+
geom_line(aes(y=Prix2),colour="blue",lwd=1)+
geom_line(aes(y=Prix3),colour="green",lwd=1)+
geom_line(aes(y=Prix4),colour="gold",lwd=1)+
geom_line(aes(y=Prix5),colour="purple",lwd=1)+
geom_line(aes(y=Prix6),colour="pink",lwd=1)+
ggtitle("Evolution des prix des 6 indices")+xlab("Temps")+ylab("Prix : base=1 le 30/11/2018")+ theme(plot.title = element_text(color="black", size=14,face="bold"))
Grâce au graphique ci-dessus on peut voir les 6 prix des fonds sur un même plan qui vient confirmer la classification en 2 sous groupes que nous avions faite juste avant. Il est cependant plus difficile de regrouper les fonds d’obligations (en jaune et violet) car n’étant pas à la même échelle, la tendance n’apparaît pas être la même.
ggplot(base, aes(x = Date, y = Rdmts1, color = VFINX)) +
geom_line() +
geom_hline(aes(yintercept=0.000636), col="red") +
theme_bw() + ggtitle("Évolution du rendement de l'indice VFINX") +
xlab("Date") + ylab("Rendement") +
scale_color_continuous(name = "Indice") +
labs(caption="Rendement moyen=0,0636%")
ggplot(base, aes(x = Date, y = Rdmts2, color = VEURX)) +
geom_line() +
geom_hline(aes(yintercept=0.000535), col="red") +
theme_bw() + ggtitle("Évolution du rendement de l'indice VEURX") +
xlab("Date") + ylab("Rendement") +
scale_color_continuous(name = "Indice") +
labs(caption="Rendement moyen=0,0535%")
ggplot(base, aes(x = Date, y = Rdmts3, color = VEIEX)) +
geom_line() +
geom_hline(aes(yintercept=0.000377), col="red") +
theme_bw() + ggtitle("Évolution du rendement de l'indice VEIEX") +
xlab("Date") + ylab("Rendement") +
scale_color_continuous(name = "Indice") +
labs(caption="Rendement moyen=0,0377%")
ggplot(base, aes(x = Date, y = Rdmts4, color = VBLTX)) +
geom_line() +
theme_bw() + ggtitle("Évolution du rendement de l'indice VBLTX") +
geom_hline(aes(yintercept=0.00084), col="red") +
xlab("Date") + ylab("Rendement") +
scale_color_continuous(name = "Indice") +
labs(caption="Rendement moyen=0,084%")
ggplot(base, aes(x = Date, y = Rdmts5, color = VBISX)) +
geom_line() +
geom_hline(aes(yintercept=0.000226), col="red") +
theme_bw() + ggtitle("Évolution du rendement de l'indice VBISX") +
xlab("Date") + ylab("Rendement") +
scale_color_continuous(name = "Indice") +
labs(caption="Rendement moyen=0,0226%")
ggplot(base, aes(x = Date, y = Rdmts6, color = VPACX)) +
geom_line() +
geom_hline(aes(yintercept=0.000336), col="red") +
theme_bw() + ggtitle("Évolution du rendement de l'indice VPACX") +
xlab("Date") + ylab("Rendement") +
scale_color_continuous(name = "Indice") +
labs(caption="Rendement moyen=0,0336%")
Ici encore en rouge nous avons le rendement moyen dont la valeur est donnée en bas à droite du graphique. Nous faisons le même constat que lorseque nous regardons la valeur des rendements dans la abse ; ils sont très volatiles. Tous les fonds ont des rendements négatifs à certaines dates, mais les rendements moyens sont eux, positifs. Nous observons un phénomène étrange pour le fond ‘VBISX’ qui a régulièrement des rendements nuls (=0), et pour la plupart compris entre 0.00097 et -0.00097, ce qui donne cette allure en “code barre” à la courbe.
En regardant les graphiques des prix des fonds nous pouvons constater plusieurs retours à la moyenne. Comme dit précedemment nous pouvons identifier 2 groupes selon l’allure de l’évolution des prix. Nous pouvons étudier en détails le fond d’obligation à court terme ‘VBISX’ et le S&P 500 ‘VFINX’.
VFINX : cet indice boursier est basé sur 500 grandes sociétés cotées sur les bourses aux Etats-Unis, il représente 80% du marché américain par sa capitalisation. L’indice connait une tendance générale à la hausse à partir de janvier 2019, après une forte baisse ; mais à quoi peut être dûe cette chute soudaine ? Selon le Stock Trader’s Almanac, le S&P 500 enregistre en moyenne un gain de 1,6% en décembre, ce qui en fait normalement le meilleur mois de l’année, on parle notamment de “rally de Noël”. Seulement, cette année là l’indice a connu son pire mois de décembre depuis la grande dépression de 1931, tout comme le Dow Jones d’ailleurs. Ces baisses soudaines de plusieurs indices phares de Wall Street sont dues aux obsèques nationales de George Bush père pour lesquelles la bourse newyorkaise est restée fermée le mercredi 5 décembre 2018. Cette fermeture a provoqué une baisse des cours, une “rupture” qui a conduit à la clôture soudaine de nombreuses positions sur ces fonds. Puis le fond a repris petit à petit de la valeur, d’où la tendance à la hausse des prix à partir de janvier 2019. Ce constat d’une forte chute en décembre 2018 est visible aussi pour les fonds VEURX, VEIEX et VPACX.
VBISX : On peut voir que le VBISX ainsi que le VBLTX n’ont pas connu cette rupture en décembre 2018, c’est parce qu’il s’agit d’obligations à court et long terme. Une règle d’or dit qu’une mauvaise année pour les actions est un bonne année pour les obligations, nous pouvons vérifier ce dicton en décembre 2018 où les actions sont en chute alors que le prix des obligations augmente fortement. Il passe ainsi de 1 (base 1 le 1er décembre 2018) à 1.011 en un mois et connait ensuite une croissance régulière jusqu’en octobre 2019 où les prix ralentissent puis décroissent légèrement par rapport au 1er décembre 2018.
par(mfrow=c(2,3))
boxplot(`base`$`VFINX`, main="VFINX", col="#FFCC00")
boxplot(`base`$`VEURX`, main="VEURX", col="#FF6600")
boxplot(`base`$`VEIEX`, main="VEIEX", col="brown")
boxplot(`base`$`VBLTX`, main="VBLTX", col="#660066")
boxplot(`base`$`VBISX`, main="VBISX", col="#3333CC")
boxplot(`base`$`VPACX`, main="VPACX", col="#009933")
Nous constatons que la moitié des indices possèdent des valeurs atypiques, points qui sont situés en dehors de la boîte :
# Statistiques descriptives
summary(base[,2:7])
## VFINX VEURX VEIEX VBLTX
## Min. :213.8 Min. :24.80 Min. :23.13 Min. :12.37
## 1st Qu.:254.8 1st Qu.:27.68 1st Qu.:25.13 1st Qu.:13.11
## Median :265.3 Median :28.45 Median :25.94 Median :13.83
## Mean :262.8 Mean :28.24 Mean :25.80 Mean :14.06
## 3rd Qu.:274.4 3rd Qu.:29.14 3rd Qu.:26.63 3rd Qu.:15.15
## Max. :291.9 Max. :30.44 Max. :27.37 Max. :15.83
## NA's :13
## VBISX VPACX
## Min. :10.00 Min. :11.02
## 1st Qu.:10.17 1st Qu.:12.08
## Median :10.40 Median :12.40
## Mean :10.34 Mean :12.37
## 3rd Qu.:10.53 3rd Qu.:12.62
## Max. :10.60 Max. :13.31
##
# Moyenne
round(sapply(base[,2:7],mean, na.rm=TRUE),4)
## VFINX VEURX VEIEX VBLTX VBISX VPACX
## 262.7904 28.2394 25.8010 14.0637 10.3441 12.3673
# Variance
round(sapply(base[,2:7],var, na.rm=TRUE),4)
## VFINX VEURX VEIEX VBLTX VBISX VPACX
## 242.8949 1.5977 0.9635 1.0332 0.0329 0.1840
# Écart-type
round(sapply(base[,2:7],sd, na.rm=TRUE),4)
## VFINX VEURX VEIEX VBLTX VBISX VPACX
## 15.5851 1.2640 0.9816 1.0165 0.1813 0.4290
# Skewness
round(sapply(base[,2:7],skewness, na.rm=TRUE),4)
## VFINX VEURX VEIEX VBLTX VBISX VPACX
## -0.6736 -0.6823 -0.6223 0.2233 -0.2381 -0.1720
# Kurtosis
round(sapply(base[,2:7],kurtosis, na.rm=TRUE),4)
## VFINX VEURX VEIEX VBLTX VBISX VPACX
## 0.1095 0.0617 -0.2437 -1.3525 -1.3451 0.3205
On constate dans un premier temps que toutes nos variables (les 6 fonds) sont homogènes puisque les écart-types sont tous inférieurs aux moyennes, sinon, on aurait parlé d’hétérogénéité. Cela se confirme par le fait que la médiane soit relativement proche de la moyenne. De plus, on peut noter que l’étendue (écart entre les valeurs minimales et maximales pour une variable donnée) est particulièrement faible pour les fonds VEIEX, VBLTX et VBISX pour lesquels il n’y avait pas de valaurs atypiques, ce constat est donc confirmé par les boîtes à moustache. Nous pouvons à présent nous interesser à la disribution des variables en regardant la skewness et la kurtosis : ces coefficients donnent une indication sur l’aplatissement et la symétrie de la distribution des variables. La loi normale se caractérise par un coefficient d’aplatissement et d’asymétrie égal à zéro. S’ils sont différents de zéro il y a 2 situations possibles pour chaque coefficient :
En terme d’asymétrie, le fond s’approchant le plus d’une loi normale est VPACX qui a une asymétrie à droite (skewness=-0.172) et celui qui s’en approche le moins est VEURX (skewness=0.682). En terme d’aplatissement c’est VFINX cette fois qui s’apparente le plus à la loi normale avec une courbe moins aplatie (kurtosis=0.11), et la séris qui s’en approche le moins est VBLTX (kurtosis=-1.345).
par(mfrow=c(2,3))
hist(base$VFINX, main="Histogramme VFINX", xlab="VFINX", ylab="Fréquences", col=brewer.pal(n = 9, name = "Greens"))
hist(base$VEURX, main="Histogramme VEURX", xlab="VEURX", ylab="Fréquences", col=brewer.pal(n = 12, name = "PuRd"))
hist(base$VEIEX, main="Histogramme VEIEX", xlab="VEIEX", ylab="Fréquences", col=brewer.pal(n = 9, name = "Purples"))
hist(base$VBLTX, main="Histogramme VBLTX", xlab="VBLTX", ylab="Fréquences", col=brewer.pal(n = 9, name = "Reds"))
hist(base$VBISX, main="Histogramme VBISX", xlab="VBISX", ylab="Fréquences", col=brewer.pal(n = 8, name = "Greys"))
hist(base$VPACX, main="Histogramme VPACX", xlab="VPACX", ylab="Fréquences", col=brewer.pal(n = 9, name = "Blues"))
is.xts(base)
## [1] FALSE
base <- as.xts(base)
round(SharpeRatio(base[,1:6], Rf=.0004167, FUN="StdDev"),3)
## VFINX VEURX VEIEX VBLTX VBISX VPACX
## StdDev Sharpe (Rf=0%, p=95%): 16.862 22.341 26.285 13.835 57.044 28.827
Le ratio de Sharpe permet de mesurer la rentabilité d’un portefeuille en fonction du risque pris. On cherchera donc le portefeuille avec le risque le plus faible pour un rendement maximal. On constate ainsi que les ratios de Sharpe sont compris entre 0 et 100%, cela signifie que l’excédent de rendement par rapport au taux sans risque est plus faible que le risque pris en lui-même. Le ratio le plus grand est celui de la série ‘VBISX’ qui s’élève à 57.04%, et le plus petit est celui de la série ‘VBLTX’ qui est de 13.84%.
# Suppression des valeurs manquantes
base1 <- na.omit(base)
# Matrice de variances, covariances
cov(base1[,13:18])
## Rdmts1 Rdmts2 Rdmts3 Rdmts4
## Rdmts1 9.237020e-05 5.892791e-05 6.055419e-05 -2.262377e-05
## Rdmts2 5.892791e-05 6.327850e-05 5.094628e-05 -1.406860e-05
## Rdmts3 6.055419e-05 5.094628e-05 7.048721e-05 -1.465844e-05
## Rdmts4 -2.262377e-05 -1.406860e-05 -1.465844e-05 3.244421e-05
## Rdmts5 -5.318794e-06 -3.521478e-06 -3.357020e-06 5.637378e-06
## Rdmts6 6.314185e-05 4.905560e-05 5.468600e-05 -1.505639e-05
## Rdmts5 Rdmts6
## Rdmts1 -5.318794e-06 6.314185e-05
## Rdmts2 -3.521478e-06 4.905560e-05
## Rdmts3 -3.357020e-06 5.468600e-05
## Rdmts4 5.637378e-06 -1.505639e-05
## Rdmts5 1.635370e-06 -3.425192e-06
## Rdmts6 -3.425192e-06 6.040946e-05
La variance la plus faible est celle du fond VBISX, les autres sont plus élevées. Concernant les covariances elles sont aussi relativement faibles ce qui signifie que la variation d’un fond impacte peu celle d’un autre. Certaines sont positives : quand un fond augmente, l’autre augmente aussi (c’est le cas par exemple pour les fonds VFINX et VEURX, VEIEX et VPACS ou encore VEURX et VEIEX). Et d’autres négatives : un fond qui augmente va faire diminuer un autre (c’est le cas pour VFINX et VBISX, VEURX et VBISX ou encore VEIEX et VBLTX).
# Matrice de corrélation
cor1 <- cor(base[,13:18], use="complete.obs", method=c("spearman"))
cor1
## Rdmts1 Rdmts2 Rdmts3 Rdmts4 Rdmts5 Rdmts6
## Rdmts1 1.0000000 0.7515246 0.7249050 -0.3390929 -0.3663049 0.8195352
## Rdmts2 0.7515246 1.0000000 0.7112393 -0.2522580 -0.3031636 0.7693714
## Rdmts3 0.7249050 0.7112393 1.0000000 -0.2260905 -0.2506148 0.8058835
## Rdmts4 -0.3390929 -0.2522580 -0.2260905 1.0000000 0.7227376 -0.2570236
## Rdmts5 -0.3663049 -0.3031636 -0.2506148 0.7227376 1.0000000 -0.2946709
## Rdmts6 0.8195352 0.7693714 0.8058835 -0.2570236 -0.2946709 1.0000000
# Corrplot
par(mfrow=c(1,1))
col <- colorRampPalette(c("#BB4444", "#EE9988", "#FFFFFF", "#77AADD", "#4477AA"))
corrplot(cor1, method="color", col=col(200),
type="upper",
addCoef.col = "black")
# Chart Correlation ; autre méthode
chart.Correlation(base[,13:18], histogram = TRUE)
Nous allons à présent analyser la matrice de corrélation en regardant les coefficients, s’ils sont compris entre 0 et 0.5 nous considérons que les variables ne sont pas corrélées, entre 0.5 et 0.6 nous pouvons supposer l’existence d’une corrélation et au delà de 0.5 nous estimons que la corrélation est forte. Au regard de la matrice de corrélation on voit que les actifs les plus corrélés sont VFINX et VPACX qui ont un coefficient de corrélation (CC) de 0.82. Ils sont suivis de près par les actifs VEIEX et VPACX dont le coefficient est de 0.81. Les moins corrélés sont VEIEX et VBLTX qui ont un CC=-0.23.
D’après le MEDAF, la diversification permet de réduire la volatilité du portefeuille tant que les actifs ne sont pas parfaitement corrélés (c’est à dire CC=1). Ici aucune pair d’actif n’est corrélée parfaitement, les corrélations les plus fortes s’élèvent à 0.82, ce qui est suffisant pour diversifier le portefeuille et ainsi réduire le risque.
On décide de prendre comme actif de référence “VBISX” qui est le fond d’obligations à long terme, car il est peu corrélé aux autres actifs, qu’il a le risque le plus faible, et qu’il n’a pas de valeurs atypiques :
round(BetaCoVariance(base[,1:6], base[,"VBISX",]),3)
## VFINX VEURX VEIEX VBLTX VBISX VPACX
## Beta Covariance: VBISX 73.719 5.03 2.345 5.573 1 1.352
round(CAPM.alpha(base[,1:6], base[, "VBISX",], Rf=0.0004167),3)
## VFINX VEURX VEIEX VBLTX VBISX VPACX
## Alpha: VBISX -499.734 -23.794 1.541 -43.517 0 -1.619
round(TreynorRatio(base[,1:6], base[, "VBISX",]),3)
## VFINX VEURX VEIEX VBLTX VBISX
## Treynor Ratio: VBISX Inf Inf Inf 7.022279e+295 6.140167e+265
## VPACX
## Treynor Ratio: VBISX 3.764811e+283
round(SFM.jensenAlpha(base[,1:6], base[, "VBISX",], na.rm=FALSE),3)
## VFINX VEURX VEIEX VBLTX VBISX
## Jensen's Alpha (Risk free = 0) Inf Inf Inf NA -1.431945e+250
## VPACX
## Jensen's Alpha (Risk free = 0) 5.090559e+283
round(MarketTiming(base[,1:6], base[, "VBISX",], Rf=0.0004167, method="TM"),3)
## Alpha Beta Gamma
## VFINX to VBISX -12289.884 2358.868 -110.692
## VEURX to VBISX -1953.962 379.133 -18.121
## VEIEX to VBISX -2033.507 396.775 -19.106
## VBLTX to VBISX 579.440 -115.220 5.854
## VBISX to VBISX 0.000 1.000 0.000
## VPACX to VBISX -313.610 61.822 -2.929
round(CoSkewness(base[,1:6], base[, "VBISX",]),5)
## VFINX VEURX VEIEX VBLTX VBISX VPACX
## Coskewness: VBISX -0.17502 -0.01872 -0.01557 -0.00134 -0.00141 -0.00379
er_1 <- mean(base$Rdmts1, na.rm=TRUE)
er_2 <- mean(base$Rdmts2, na.rm=TRUE)
er_3 <- mean(base$Rdmts3, na.rm=TRUE)
er_4 <- mean(base$Rdmts4, na.rm=TRUE)
er_5 <- mean(base$Rdmts5, na.rm=TRUE)
er_6 <- mean(base$Rdmts6, na.rm=TRUE)
PE <- 1/6*er_1+1/6*er_2+1/6*er_3+1/6*er_4+1/6*er_5+1/6*er_6
round(PE*100,5)
## [1] 0.04918
sd_1 <- sd(base$Rdmts1, na.rm=TRUE)
sd_2 <- sd(base$Rdmts2, na.rm=TRUE)
sd_3 <- sd(base$Rdmts3, na.rm=TRUE)
sd_4 <- sd(base$Rdmts4, na.rm=TRUE)
sd_5 <- sd(base$Rdmts5, na.rm=TRUE)
sd_6 <- sd(base$Rdmts6, na.rm=TRUE)
SD <- 1/6*sd_1+1/6*sd_2+1/6*sd_3+1/6*sd_4+1/6*sd_5+1/6*sd_6
round(SD,5)
## [1] 0.00668
Notre portefeuille équipondéré, c’est à dire avec un poids de 1/6 pour chaque indice, composé des 6 fonds a un rendement moyen de 0.049%, c’est un tout petit peu moins que le rendement moyen du fond ‘VEURX’. Son écart-type est de 0.0067 ce qui est relativement faible par rapport aux écart-types des fonds, analysés en question 4 - ce portefeuille équipondéré est donc peu risqué.
ER <- c(er_1, er_2, er_3, er_4, er_5, er_6)
VAR <- c(sd_1^2, sd_2^2, sd_3^2, sd_4^2, sd_5^2, sd_6^2)
Légende <- c("VFINX", "VEURX", "VEIEX", "VBLTX", "VBISX", "VPACX")
ggplot(mapping=aes(VAR,ER*100)) + geom_point(mapping=aes(VAR,ER*100, color=Légende), size=5) +
labs(title="Rentabilité esperée et risque d'un portefeuille",
x="Risque attendu",
y="Rendement moyen esperé du portefeuille") +
theme_light()
Un portefeuille efficient est celui qui présente le couple risque-rentabilité optimal pour un investisseur. La théorie du portefeuille efficient a été développée par Harry Markowitz dans les années 50 afin d’offrir la rentabilité maximale pour un niveau de risque aussi faible que possible. Ainsi, un titre est dit inefficient s’il est compris dans la zone qui se situe à droite de la frontière d’efficience du portefeuille, comme c’est visible sur le schéma suivant :
On voit donc que 5 indices ont tendance à se retrouver dans la zone d’inefficience ; l’indice qui apparait comme étant le plus intéressant est donc le fond d’obligations à long terme ‘VBLTX’ qui a un rendement moyen esperé largement supérieur aux autres fonds, de plus le risque attendu est relativement faible. Tous les autres titres semblent inefficients puisqu’ils ne se situent pas sur la frontière d’efficience.
base1 <- na.omit(base)
base1 <- data.table(base1)
# I) Retour attendu
er_x <- mean(base1$Rdmts1, na.rm=TRUE)
er_y <- mean(base1$Rdmts2, na.rm=TRUE)
er_z <- mean(base1$Rdmts3, na.rm=TRUE)
# II) Risque
sd_x <- sd(base1$Rdmts1, na.rm=TRUE)
sd_y <- sd(base1$Rdmts2, na.rm=TRUE)
sd_z <- sd(base1$Rdmts3, na.rm=TRUE)
# III) Covariance
cov_xy <- cov(base1$Rdmts1, base1$Rdmts2)
cov_xz <- cov(base1$Rdmts1, base1$Rdmts3)
cov_yz <- cov(base1$Rdmts2, base1$Rdmts3)
# On créé des poids pour tous les portefeuilles possibles
x_weights <- seq(from = 0, to = 1, length.out = 1000)
# Puis on créé un tableau qui regroupe les poids
Poids <- data.table(wx = rep(x_weights, each = length(x_weights)),
wy = rep(x_weights, length(x_weights)))
Poids[, wz := 1 - wx - wy]
# On calcule les risque et rendements des 1000 portefeuilles possibles
Poids[, ':=' (er_p = wx * er_x + wy * er_y + wz * er_z,
sd_p = sqrt(wx^2 * sd_x^2 +
wy^2 * sd_y^2 +
wz^2 * sd_z^2 +
2 * wx * wy * cov_xy +
2 * wx * wz * cov_xz +
2 * wy * wz * cov_yz))]
# On fait attention à ne garder que les poids positifs
Poids <- Poids[wx >= 0 & wy >= 0 & wz >= 0]
# Finalement on plot les valeurs
ggplot() +
geom_point(data = Poids, aes(x = sd_p, y = er_p, color = wx - wz)) +
geom_point(data = data.table(sd = c(sd_x, sd_y, sd_z), mean = c(er_x, er_y, er_z)),
aes(x = sd, y = mean), color = "red", size = 3, shape = 18) +
theme_bw() + ggtitle("Portefeuilles possibles avec 3 titres") +
xlab("Risque") + ylab("Retour attendu") +
scale_y_continuous(label = percent, limits = NULL) +
scale_x_continuous(limits = NULL) +
scale_color_gradientn(colors = c("red", "blue", "yellow"),
name = expression(omega[x] - omega[z]), labels = percent)
On voit que toutes les combinaisons de portefeuilles ont un rendement espéré compris entre 0.0438% (qui est le retour du fond ‘VEIEX’) et 0.0592% (qui est celui du fond ‘VFINX’). La distribution des portefeuilles forme une banane bornée par les fonds ‘VFINX’ et ‘VEIEX’ en terme de rendement, et avec des volatilités allant de 0.75 environ à celle du fond ‘VFINX’ qui est de 0.0096.
#Frontière d'efficience sans vente à découvert
calcEFParams1 <- function(rets) {
retbar <- colMeans(rets, na.rm = T)
covs <- var(rets, na.rm = T)
invS <- solve(covs)
i <- matrix(1, nrow = length(retbar))
alpha <- t(i) %*% invS %*% i
beta <- t(i) %*% invS %*% retbar
gamma <- t(retbar) %*% invS %*% retbar
delta <- alpha * gamma - beta * beta
retlist <- list(alpha = as.numeric(alpha),
beta = as.numeric(beta),
gamma = as.numeric(gamma),
delta = as.numeric(delta))
return(retlist)
}
## On applique le calcEFParams1 à notre jeu de données
# On créé d'abord une nouvelle base ne contenant que les 3 indices qui nous interessent
base2 <- base [, c("Rdmts1", "Rdmts2", "Rdmts3")]
base2 <- na.omit(base2)
base2 <- data.table(base2)
abcds <- calcEFParams1(base2)
abcds
## $alpha
## [1] 17729.31
##
## $beta
## [1] 8.360378
##
## $gamma
## [1] 0.00567662
##
## $delta
## [1] 30.74666
calcEFValues <- function(x, base2, upper = T) {
alpha <- base2$alpha
beta <- base2$beta
gamma <- base2$gamma
delta <- base2$delta
if (upper) {
retval <- beta / alpha + sqrt((beta / alpha) ^ 2 - (gamma - delta * x ^ 2) / (alpha))
} else {
retval <- beta / alpha - sqrt((beta / alpha) ^ 2 - (gamma - delta * x ^ 2) / (alpha))
}
return(retval)
}
# On calcule le couple risque-rendement des 3 actifs
RR <- melt(base2)[, .(er = mean(value),
sd = sd(value)), by = variable]
# On sort le graphique
Actifs <- c("VFINX", "VEURX", "VEIEX")
ggplot(RR, mapping=aes(sd,er)) +
geom_point(mapping=aes(sd,er, color=Actifs), size = 4, shape=19) +
stat_function(fun = calcEFValues, args = list(base2 = abcds, upper = T), n = 10000,
color = "grey", size = 1) +
stat_function(fun = calcEFValues, args = list(base2 = abcds, upper = F), n = 10000,
color = "grey", size = 1) +
theme_bw() + ggtitle("Frontière d'efficience") +
xlab("Risque") + ylab("Rendements attendus") +
scale_y_continuous(label = percent, limits = NULL) +
scale_x_continuous(limits = c(0.0075,0.01))
On voit donc que les titres ‘VEURX’, ‘VEIEX’ et ‘VFINX’ sont situés dans la zone d’inefficience, c’est à dire à droite de la frontière d’efficience. Le portefeuille qui s’en rapproche le plus est l’indice boursier européen ‘VEURX’.
On peut à présent déterminer le portefeuille de variance minimale (PVM), sur la frontière d’efficience qui donne tous les portefeuilles possibles en variant les poids, c’est donc le portefeuille le moins risqué. Sur le graphique précedent il se serait trouvé approximativement à la jonction entre les courbes du haut et du bas de la frontière d’efficience.
# Création des objets nécéssaires pour trouver le PVM
# Covariances
cov.mat <- cov(base2)
# Rendements moyens
er <- c(er_x, er_y, er_z)
# Ecarts types moyens
sd.vec <- c(sd_x, sd_y, sd_z)
# Poids
x.msft = runif(100, min=-1.5, max=1.5)
x.nord = runif(100, min=-1.5, max=1.5)
x.sbux = 1 - x.msft - x.nord
# Calcul du portefeuille de variance minimale
getMinVariancePortfolio <- function(er,cov.mat,Actifs) {
U <- rep(1, length(er))
O <- solve(cov.mat)
w <- O%*%U /as.numeric(t(U)%*%O%*% U)
Risk <- sqrt(t(w) %*% cov.mat %*% w)
ExpReturn <- t(w) %*% er
Weights <- `names<-`(round(w, 5), Actifs)
list(Weights = t(Weights),
ExpReturn = round(as.numeric(ExpReturn), 5),
Risk = round(as.numeric(Risk), 5))
}
(MVP <- getMinVariancePortfolio(er, cov.mat, Actifs))
## $Weights
## Rdmts1 Rdmts2 Rdmts3
## [1,] -0.02251 0.63563 0.38688
##
## $ExpReturn
## [1] 5e-04
##
## $Risk
## [1] 0.00751
# Représentation graphique du PVM avec les 3 titres et tous les autres portefeuilles possibles
cex.val=1.15
plot(sd.vec, er, ylim=c(0.0002, 0.0008), xlim=c(0.006, 0.015), ylab="Rendement espéré",
xlab="Risque", pch=16, col="blue", cex=2.5, main="Portefeuille de variance minimale")
for (i in 1:length(x.msft)) {
z.vec = c(x.msft[i], x.nord[i], x.sbux[i])
mu.p = crossprod(z.vec,er)
sig.p = sqrt(t(z.vec)%*%cov.mat%*%z.vec)
points(sig.p, mu.p, pch=16, col="grey", cex=1)
}
text(sd.vec, er, labels=Actifs, pos=4, cex = cex.val)
points(MVP$Risk, MVP$ExpReturn, pch=16, cex=2.5, col="green")
text(MVP$Risk, MVP$ExpReturn, labels="PVM", pos=2.5, cex = cex.val)
# Tableau récapitulatif des risques et rendements associés à chaque titres et au PVM
resultats <- data.frame(Rendements=c(er*100,MVP$ExpReturn*100), Risque=c(sd.vec,MVP$Risk), row.names = c("VFINX","VEURX","VEIEX","PVM"))
resultats
## Rendements Risque
## VFINX 0.05922797 0.009610941
## VEURX 0.05481996 0.007954778
## VEIEX 0.04383130 0.008395666
## PVM 0.05000000 0.007510000
Le PVM a donc un rendement de 0.05% et un écart-type de 0.008. Dans le tableau ci dessus on peut trouver un récapitulatif des rendements et des risque associés à chaque titre, on peut donc comparer ceux du PVM à ces derniers. Il apparait donc que le portefeuille de variance minimale est le moins risqué (logique !), il n’est pourtant pas celui qui a le rendement le plus faible : le fond ‘VEIEX’ a un rendement plus faible puisqu’il est de 0.0438% < 0.05%. On peut voir aussi qu’il y a des pondérations négatives dans le PVM car il est composé de 63.56% de ‘VEURX’, 38.69% de ‘VEIEX’ et -2.25% de ‘VFINX’.
# Portefeuille tangent
getTangentPortfolio <- function(er,cov.mat,Actifs,Rf = 0.02/12){
U <- rep(1, length(er))
muE <- (er - Rf * U) # excedent de rendement
O <- solve(cov.mat) # inverse de la matrice
w <- (O %*% muE)/ as.numeric(t(U)%*%O%*%muE)
Risk <- sqrt(t(w) %*% cov.mat %*% w)
ExpReturn <- t(w) %*% er
Weights <- `names<-`(round(w,5), Actifs)
list(Weights = t(Weights),
ExpReturn = as.numeric(ExpReturn),
Risk = as.numeric(Risk))
}
(GTP <- getTangentPortfolio(er, cov.mat, Actifs))
## $Weights
## Rdmts1 Rdmts2 Rdmts3
## [1,] -0.16772 0.54691 0.6208
##
## $ExpReturn
## [1] 0.0004725885
##
## $Risk
## [1] 0.007613292
# Portefeuille efficient
mu0=0.05
getEfficientPortfolio <- function(er, cov.mat, Actifs, mu0=0.05) {
U <- rep(1, length(er))
O <- solve(cov.mat)
A <- as.numeric(t(U) %*% O %*% er)
B <- as.numeric(t(er) %*% O %*% er)
C <- as.numeric(t(U) %*% O %*% U)
D <- B * C - A * A
E <- O %*% ( - A * U + C * er) / D
F <- O %*% (B * U - A * er) / D
w <- E * mu0 + F
Risk <- sqrt(t(w) %*% cov.mat %*% w)
ExpReturn <- t(w) %*% er
Weights <- `names<-`(round(w,5), Actifs)
list(Weights = t(Weights),
ExpReturn = as.numeric(round(ExpReturn,5)),
Risk = as.numeric(round(Risk,5)))
}
(mu0 <- getEfficientPortfolio(er, cov.mat, Actifs))
## $Weights
## Rdmts1 Rdmts2 Rdmts3
## [1,] 223.8344 137.402 -360.2364
##
## $ExpReturn
## [1] 0.05
##
## $Risk
## [1] 1.92456
# Table récapitulative à laquelle on ajoute les valeurs du portefeuille tangent
resultats <- data.frame(Rendements=c(er*100, MVP$ExpReturn*100, GTP$ExpReturn*100), Risque = c(sd.vec, MVP$Risk, GTP$Risk), row.names = c("VFINX", "VEURX", "VEIEX", "P.VM", "P.tangent"))
resultats
## Rendements Risque
## VFINX 0.05922797 0.009610941
## VEURX 0.05481996 0.007954778
## VEIEX 0.04383130 0.008395666
## P.VM 0.05000000 0.007510000
## P.tangent 0.04725885 0.007613292
Un portefeuille tangent est un portefeuille possédant le ratio de Sharpe le plus élevé, dans le cadre du MEDAF, le portefeuille tangent est le portefeuille de marché. C’est le point de tangence entre la frontiere d’efficience et la droite de marché des capitaux ou Capital Market Line (CML), il offre donc le meilleur excédent de rendement par unité de risque, c’est pour cela qu’il est aussi appelé “portefeuille super-efficient”. Dans notre analyse il a un rendement de 0.047% (rendement compris entre celui du fond ‘VEIEX’ et du PVM) pour un risque de 0.0076 (c’est le deuixème risque le plus faible après celui du PVM).
Enfin on peut représenter graphiquement tous ces portefeuilles sur un même graphique qui conclura et résumera cette partie sur la théorie moderne de portefeuille.
# Frontière efficiente
getEfficientFrontier <- function(er, cov.mat, Actifs, Nb = 20){
mu0 <- seq(getMinVariancePortfolio(er, cov.mat, Actifs)$ExpReturn, 0.08, length.out = Nb)
ExpReturn <- NULL
Risk <- NULL
Weights <- data.frame()
for (i in 1:Nb) {
list <- getEfficientPortfolio(er, cov.mat, Actifs, mu0[i])
ExpReturn <- c(ExpReturn, list$ExpReturn)
Risk <- c(Risk, list$Risk)
Weights <- rbind(Weights, list$Weights)
}
list(Weights= data.frame(Weights),
ExpReturn = as.vector(ExpReturn),
Risk = as.vector(Risk))
}
EFF <- getEfficientFrontier(er, cov.mat, Actifs)
# Capital market line
getCML <- function(er, cov.mat, Actifs, Rf = 0.005) {
mu0 <- seq(Rf,0.08,length.out = 20)
U <- rep(1, length(er))
muE <- (er - Rf * U) # excedent de rendement
mu0E <- (mu0 - Rf) # excedent sur le rendement du portefeuille
O <- solve(cov.mat) # inverse de la matrice
ExpReturn <- NULL
Risk <- NULL
Weights <- data.frame()
w_r <- sapply(mu0E, function(x, muE, O) {
x * ((O %*% muE) / as.numeric(t(muE) %*% O %*% muE))
}, O = O, muE = muE)
w_f = 1 - colSums(w_r)
w_r <- `rownames<-`(round(w_r, 5), Actifs)
Weights = cbind(t(w_r),Rf=w_f)
ExpReturn = t(w_r) %*% er + w_f * Rf
Risk = sqrt(diag(t(w_r) %*% cov.mat %*% w_r))
list(Weights = data.frame(Weights), ExpReturn = as.vector(ExpReturn), Risk = Risk)
}
CML <- getCML(er, cov.mat, Actifs)
####### On plot le tout
data = data.frame(ExpReturn = er*100, Risk = sqrt(diag(cov.mat)))
ExpReturn <- er*100
ExpReturn
## [1] 0.05922797 0.05481996 0.04383130
Risk <- sqrt(diag(cov.mat))
Risk
## Rdmts1 Rdmts2 Rdmts3
## 0.009391830 0.007799301 0.008272231
plot <- ggplot(data, mapping=aes(x = Risk, y = ExpReturn)) +
theme_light() +
theme(plot.title = element_text( face = "bold"),
plot.background = element_rect(fill = "white"),
axis.line.x = element_line(color = "black", size = 1),
axis.line.y = element_line(color = "black", size = 1)) +
geom_point(mapping=aes(Risk, ExpReturn, colour = Actifs), size = 2) +
geom_text_repel(label = Actifs,size = 2.5) +
scale_x_continuous(minor_breaks = seq(0.006, 0.01, 0.005) ,
limits = c(0.006, 0.01),
labels = dollar_format(prefix = "")) +
scale_y_continuous(minor_breaks = seq(0.02, 0.7, 0.005) ,
limits = c(0.04, 0.065),
labels = dollar_format(suffix = "%", prefix = "")) +
labs(x = "Risque", y ="Retour esperé") +
ggtitle("Graphique récapitulatif des portefeuilles")
plot <- plot + geom_line(data = data.frame(Risk1 = EFF$Risk, ExpReturn1 = EFF$ExpReturn*100),
aes(x = Risk1, y = ExpReturn1), colour = "red3", size = 1)
plot <- plot + geom_line(data = data.frame(Risk2 = CML$Risk, ExpReturn2 = CML$ExpReturn*100),
aes(x = Risk2, y = ExpReturn2), colour = "darkblue", size = 1)
allPortfolio <- data.frame(ExpReturn = c(MVP$ExpReturn*100, GTP$ExpReturn*100),
Risk = c(MVP$Risk, GTP$Risk))
plot <- plot + geom_point(data = allPortfolio, shape = 16,
colour = "red3", size =2) +
geom_text_repel(data = data.frame(allPortfolio,
label = c("PVM", "P.tangent")),
aes(x = Risk, y = ExpReturn, label = label), size = 3)
plot
Ainsi au cours de cette analyse nous avons étudié la rentabilité et le risque associés à chaque fond : nous avons vu qu’en regardant un certain nombre de critères (ratio de Sharpe, rendements, prix, risque, alpha, beta etc.) le fond le plus rentable semble être le fond d’obligation à long terme ‘VBLTX’. Les autres fonds ont soit des rendements nettement inférieurs qui les rendent nettement mois attractif, soit des risques plus élevés qui ont le même effet. Dans la deuxième partie nous avons retenu seulement les 3 premiers fonds (VFINX, VEURX et VEIEX) puis nous avons étudier la théorie de portefeuille sur ces derniers. Nous avons ainsi pu trouver le portefeuille de variance minimale ainsi que le portefeuille tangent ; pour ces 2 derniers il y avait des pondérations négatives c’est à dire que le poids d’un fond était négatif dans ces portefeuilles, il s’agit du fond ’VFINX. C’est donc logique puisque ce dernier se situe dans la zone d’inefficience, les portefeuilles tangents et de variance minimale sont efficients puisqu’ils se trouvent sur la frontière d’efficience ; c’est pour cela qu’ils ont une pondération négative du fond VFINX.